﻿/// <reference path="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1-vsdoc.js" />
var container = undefined;

window.onload = function () {
    container = $("#game_container");
    container.append($("#cr-stage"));

    var start_time = new Date().getTime();
    container.data("start", start_time);
};

//Global Variables
var SCENE_ID_LOADING = "loading";
var SCENE_ID_MAIN = "main";
var ASSET_PATH_CRAFTYSPRITE = "images/Spritesheets/crafty-sprite.png";
var ASSET_PATH_MAZEGRID = "images/MazeImages/15.jpg";
var ASSET_WALL_HORI = "images/Wall/top.jpg";
var ASSET_WALL_VER = "images/Wall/left.jpg";
var ASSET_PLAYER = "images/MazeImages/player.jpg";
var WALL_SIZE = 8;
var BG_LAYER_1 = 1;
var BG_LAYER_2 = 2;
var BG_LAYER_3 = 3;
var BG_LAYER_4 = 4;
var SIDE_UP = 0;
var SIDE_LEFT = 1;
var SIDE_DOWN = 2;
var SIDE_RIGHT = 3;
var SPEED = 4;

var SQUARE_SIZE = 16;
var WIDTH = SQUARE_SIZE * 30;
var HEIGHT = SQUARE_SIZE * 30;

var flower;
var finish;
var player1;

Array.prototype.contains = function (obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
};

function MazeGrid(posX, posY, wallType) {
    this.posX = posX;
    this.posY = posY;
    this.wallType = wallType;
    this.gridSize = 30;
}

MazeGrid.prototype.IsValidKey = function (key) {
    return this.validKeys.contains(key);
};

function MazeEntity(jsonStr, totalGrid) {
    this.grids = new Array();
    var k = 0;
    for (var i in jsonStr) {
        this.grids[k] = new MazeGrid(jsonStr[i].posX, jsonStr[i].posY, jsonStr[i].wallType);
        k++;
    }
    this.total = totalGrid;
}

function MakeWall(posX, posY, side) {
    var path;
    if (side === SIDE_UP || side === SIDE_DOWN) {
        path = ASSET_WALL_HORI;
    } else {
        path = ASSET_WALL_VER;
    }
    Crafty.e("2D,DOM,Image,solid").attr(
        { x: posX * 30, y: posY * 30, z: BG_LAYER_4 }
    ).image(path);

}

function GameMain(maze_data, height, width) {
    //Fetch map data from maze gen service
    "use strict";
    WIDTH = width * 30 + 10;
    HEIGHT = height * 30 + 20;
    //console.log("before: " + width);
    var maze_entity = new MazeEntity(JSON.parse(maze_data), height * width);
    Crafty.init(WIDTH, HEIGHT);
    Crafty.canvas.init();

    // Turn the sprite map into usable components
    Crafty.sprite(8, ASSET_PATH_CRAFTYSPRITE, {
        grass1: [0, 0],
        grass2: [1, 0],
        grass3: [2, 0],
        grass4: [3, 0],
        flower: [0, 1],
        bush1: [0, 2],
        bush2: [1, 2],
        player: [0, 3]
    });

    function GenWorld() {
        var x = maze_entity.grids[0].posX;
        var y = maze_entity.grids[0].posY;
        MakeWall(x, y, SIDE_UP);

        for (var i = 0; i < maze_entity.total; i++) {
            x = maze_entity.grids[i].posX;
            y = maze_entity.grids[i].posY;

            Crafty.e("2D, DOM, wholeGrid")
                .attr({ x: maze_entity.grids[i].posX * 1, y: maze_entity.grids[i].posY * 1, z: BG_LAYER_2 });
            switch (maze_entity.grids[i].wallType) {
                case 0:
                    MakeWall(x, y, SIDE_LEFT);
                    MakeWall(x, y, SIDE_UP);
                    MakeWall(x, y + 1, SIDE_DOWN);
                    MakeWall(x + 1, y, SIDE_RIGHT);
                    break;
                case 1:
                    MakeWall(x, y, SIDE_RIGHT);
                    MakeWall(x, y, SIDE_UP);
                    MakeWall(x, y + 1, SIDE_DOWN);
                    break;
                case 2:
                    MakeWall(x, y, SIDE_LEFT);
                    MakeWall(x, y, SIDE_UP);
                    MakeWall(x + 1, y, SIDE_RIGHT);
                    break;
                case 3:
                    MakeWall(x, y, SIDE_UP);
                    MakeWall(x + 1, y, SIDE_RIGHT);
                    break;
                case 4:
                    MakeWall(x, y, SIDE_LEFT);
                    MakeWall(x, y, SIDE_UP);
                    MakeWall(x, y + 1, SIDE_DOWN);
                    break;
                case 5:
                    MakeWall(x, y, SIDE_UP);
                    MakeWall(x, y + 1, SIDE_DOWN);
                    break;
                case 6:
                    MakeWall(x, y, SIDE_LEFT);
                    MakeWall(x, y, SIDE_UP);
                    break;
                case 7:
                    MakeWall(x, y, SIDE_UP);
                    break;
                case 8:
                    MakeWall(x, y, SIDE_LEFT);
                    MakeWall(x + 1, y, SIDE_RIGHT);
                    MakeWall(x, y + 1, SIDE_DOWN);
                    break;
                case 9:
                    MakeWall(x + 1, y, SIDE_RIGHT);
                    MakeWall(x, y + 1, SIDE_DOWN);
                    break;
                case 10:
                    MakeWall(x, y, SIDE_LEFT);
                    MakeWall(x + 1, y, SIDE_RIGHT);
                    break;
                case 11:
                    MakeWall(x + 1, y, SIDE_RIGHT);
                    break;
                case 12:
                    MakeWall(x, y + 1, SIDE_DOWN);
                    MakeWall(x, y, SIDE_LEFT);
                    break;
                case 13:
                    MakeWall(x, y + 1, SIDE_DOWN);
                    break;
                case 14:
                    MakeWall(x, y, SIDE_LEFT);
                    break;
                case 15:
                    break;
            }
        }
    }

    //turn the sprite map into usable components
    Crafty.sprite(16, "sprite.png", {
        grass1: [0, 0],
        grass2: [1, 0],
        grass3: [2, 0],
        grass4: [3, 0],
        flower: [0, 1],
        bush1: [0, 2],
        bush2: [1, 2],
        player: [0, 3],
        enemy: [0, 3],
        banana: [4, 0],
        empty: [4, 0]
    });

    Crafty.scene(SCENE_ID_LOADING, function () {
        Crafty.load([ASSET_PATH_CRAFTYSPRITE, ASSET_PATH_MAZEGRID, ASSET_WALL_HORI, ASSET_WALL_VER], function () {

            Crafty.scene(SCENE_ID_MAIN);
        });
        var loadindText = "Loading......";
        var bg = Crafty.e("2D, DOM, grass, grass1");
        Crafty.background(bg);
        Crafty.e("2D, DOM, Text").attr({ x: width * 30 / 2 - loadindText.length, y: height * 30 / 2 })
            .text(loadindText)
            .css({ "text-align": "center" });
    }
    );

    Crafty.scene(SCENE_ID_LOADING);

    Crafty.scene(SCENE_ID_MAIN, function () {
        GenWorld();

        flower = Crafty.e("2D, DOM, flower, flower")
        .attr({ x: width * 10, y: height * 10, z: BG_LAYER_3 })

        finish = Crafty.e("2D, DOM, finish, bush1")
        .attr({ x: WIDTH-30, y: HEIGHT-30, z: BG_LAYER_3 })
        console.log("after:", width, SQUARE_SIZE);
        //create our player entity with some premade components
        player1 = Crafty.e("2D, DOM, Ape, player, LeftControls, BombDropper")
    .attr({ x: 4, y: 4, z: BG_LAYER_4 })
    .leftControls(SPEED)
    .Ape();
    });

    //DEFINE CONTROLS//

    Crafty.c("LeftControls", {
        init: function () {
            this.requires('Multiway');
        },

        leftControls: function (speed) {
            this.multiway(speed, { W: -90, S: 90, D: 0, A: 180 })
            return this;
        }
    });

    Crafty.c("RightControls", {
        init: function () {
            this.requires('Multiway');
        },

        rightControls: function (speed) {
            this.multiway(speed, { I: -90, K: 90, L: 0, J: 180 })
            return this;
        }
    });

    Crafty.c('Ape', {
        Ape: function () {
            //setup animations
            this.requires("SpriteAnimation, Collision, Grid")
        	.animate("walk_left", 6, 3, 8)
        	.animate("walk_right", 9, 3, 11)
        	.animate("walk_up", 3, 3, 5)
        	.animate("walk_down", 0, 3, 2)

            //change direction when a direction change event is received
        	.bind("NewDirection",
            	function (direction) {
            	    if (direction.x < 0) {
            	        if (!this.isPlaying("walk_left")) {
            	            this.stop().animate("walk_left", 10, -1);
            	            $("#cr-stage").data("position", {
            	                x: direction.x,
            	                y: direction.y,
            	                direction: "left"
            	            });
            	        }
            	    }
            	    if (direction.x > 0) {
            	        if (!this.isPlaying("walk_right")) {
            	            this.stop().animate("walk_right", 10, -1);
            	            $("#cr-stage").data("position", {
            	                x: direction.x,
            	                y: direction.y,
            	                direction: "right"
            	            });
            	        }
            	    }
            	    if (direction.y < 0) {
            	        if (!this.isPlaying("walk_up")) {
            	            this.stop().animate("walk_up", 10, -1);
            	            $("#cr-stage").data("position", {
            	                x: direction.x,
            	                y: direction.y,
            	                direction: "up"
            	            });
            	        }
            	    }
            	    if (direction.y > 0) {
            	        if (!this.isPlaying("walk_down")) {
            	            this.stop().animate("walk_down", 10, -1);
            	            $("#cr-stage").data("position", {
            	                x: direction.x,
            	                y: direction.y,
            	                direction: "down"
            	            });
            	        }
            	    }
            	    if (!direction.x && !direction.y) {
            	        this.stop();
            	    }
            	})

        	.onHit("solid", function () {
        	    //Move unit out of solid tile
        	})

            .onHit("player", function () {
                //Move unit out of solid tile
            })

        	.bind('Moved', function (from) {
        	    if (this.hit('solid') || this.hit('player')) {
        	        this.attr({ x: from.x, y: from.y });
        	    } else if (this.hit('flower')) {
        	        flower.destroy();
        	    } else if (this.hit('finish')) {
        	        var end_time = new Date().getTime();
        	        var timestamp = end_time - container.data("start");

        	        player1.destroy(); // remove user from screen

        	        //AJAX Call to notify the server that the maze is complete
        	        $.ajax({
        	            type: "POST",
        	            url: "Game.aspx/BestScore",
        	            data: "{'score': '" + timestamp + "'}",
        	            contentType: "application/json; charset=utf-8",
        	            dataType: "json"
        	        }).done(function (response, textStatus, jqXHR) {
        	            if (response && response.d) {
        	                var time = parseInt(response.d) / 1000;
        	                alert("You finished in: " + time + "s");
        	                redirectToFinish();
        	            } else {
        	                alert("Error");
        	            }
        	        });
        	    }
        	})

        	.onHit("fire", function () {
        	    this.destroy();
        	    // Subtract life and play scream sound :-)
        	});
            return this;
        }
    });
};

function redirectToFinish() {
    $.ajax({
        type: "POST",
        url: "Game.aspx/Finish_Maze",
        data: "",
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    });
}


//**MULTIPLAYER HANDLING**//

//Send an update to the server about the current coordinates
function send_coord_server(i, x, y, direction) {
    //Send update to server
    var method, time, data;
    time = new Date().getTime();
    data = "{'timestamp': " + time + ", 'x': " + x + ", 'y': " + y;
    if (i < 0) {
        data = data + ", 'direction': '" + direction + "'}";
        method = "UpdateMovement";
    } else if (i > 0) {
        data = data + "}";
        method = "Halt";
    } else {
        return;
    }
    $.ajax({
        type: "POST",
        url: "Game.aspx/" + method,
        data: data,
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    }).done(function (response, textStatus, jqXHR) {
        if (response && response.d) {
            console.log("Server says: " + response.d);
        } else {
            console.log("Error");
        }
    });
}

//Check the other player's progress
function poll_server() {
    $.ajax({
        type: "POST",
        url: "Game.aspx/CheckChanges",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json"
    }).done(function (response, textStatus, jqXHR) {
        console.dir(response);
        poll_server();
    });
}
//poll_server();

$(function () {
    $(document).one('keydown.counter', handleAction);
});


function handleAction(e1) {
    console.log("keydown");
    var position = $("#cr-stage").data("position");
    send_coord_server(1, position.x, position.y, position.direction);
    $(document).bind('keyup.counter', function (e2) {
        console.log("keyup");
        var position = $("#cr-stage").data("position");
        send_coord_server(-1, position.x, position.y);
        if (e1.keyCode == e2.keyCode) {
            $(document).unbind('keyup.counter').one('keydown.counter', handleAction);
        }
    });
}
